#include "crc.hpp"
#include "debug.hpp"

namespace fur
{
   namespace
   {
      uint32_t crctab[256];
      
      void crc_init(void) throw()
      {
	 int i;
	 int j;
	 uint32_t a;
	 for (i = 0; i < 256; ++i)
	 {
	    a = i;
	    for (j = 0; j < 8; ++j)
	       a = (a & 1) ? (a >> 1) ^ 0xEDB88320 : (a >> 1);
	    crctab[i] = a;
	 }
      }
   }

   uint32_t crc(uint32_t startcrc, const void *begin, size_t size) throw()
   {
      size_t i;
      const uint8_t *data = reinterpret_cast<const uint8_t*>(begin);
      if (crctab[0] == 0)
	 crc_init();
      for (i = 0; i < size; ++i)
      {
	 startcrc = crctab[static_cast<uint8_t>(startcrc ^ data[i])] ^ (startcrc >> 8);
      }

      dprint("crc:size=%u\tcrc=%u\n", size, startcrc);
      return startcrc;
   }
} // end of namespace fur
